home *** CD-ROM | disk | FTP | other *** search
- /* 4D Navigator ©1991, Jerry D. Hedden, All Rights Reserved
-
- The 4D Navigator program, source code, documenation, and icon imagery are
- freely redistributable, but may not be modified in any way, or used in part
- or in whole without the express written consent of the author. Images
- generated by the 4D Navigator program may be used for any purpose provided
- credit is given to the program's author.
-
- Jerry D. Hedden
- 28 Windemere Dr.
- Sicklerville, NJ 08081
- Phone: (609)629-3975
- Email: Hedden@ESDSDF.DNet.GE.com
-
- ===========================================================================
-
- This source code REQUIRES Aztec 'C' v3.6a. It probably cannot be handled
- by any other compiler because of the assumed register usage within the
- embedded assembly code. Make with the following:
-
- as startup
- cc +x3 -e500 -z10000 4d
- ln -m -o "4D Navigator" startup.o 4d.o -lc
-
- ===========================================================================
-
- The following copyright notice accompanied the source code for Palette
- Requester which was used as a model for this program's Color and View
- Parameter requesters.
-
- Palette Requester -- (c) Copyright 1989 Jonathan Potter
- This program is freely redistributable, although all rights to it remain
- with the author. It may be used freely in any program as long as this
- notice remains intact, however, if you do this, please mention the author
- in the program. If you wish to use this in a commercial program of any
- kind, you must register with a $15 donation.
- Please send donations, bug reports, comments and suggestions to :
- Jonathan Potter
- 3 William Street
- Clarence Park 5034
- South Australia
- Australia
-
- ===========================================================================
-
- History:
-
- v1.00 - 10 Aug 1991
- Initial release
-
- **************************************************************************/
-
- #include <intuition/intuition.h>
-
- #define TIMING 0
- #define DEBUG 0
-
- /* corrects <exec/memory.h> long integer problems */
- #define CLEARED_CHIP 0x00010002L
-
- /* determines "grid spacing" */
- #define INTERVAL 18 /* degrees */
- #define SEGMENTS (360/INTERVAL)
- #define ONE80 (SEGMENTS/2)
- #define LATRNG ((SEGMENTS/4)-1)
- #define NUM_GRID_PTS (long)(SEGMENTS*LATRNG*SEGMENTS)
-
- /* circle constants */
- #define PI (float)3.1415926535897932384626433832795
- #define HALF_DEG (float)(PI/360.0)
-
- /* rotation constants */
- #define RESTART -1
- #define STOPPED 0
- #define TEN_DEGREES 20
- #define NINETY_DEGREES 180
- #define THREE_SIXTY 720
-
- /* the 4 coordinates */
- #define X 0L
- #define Y 1L
- #define Z 2L
- #define W 3L
-
- /* required libraries */
- struct Library *IntuitionBase, *GfxBase, *MathBase, *MathTransBase,
- *_OpenLibrary();
-
- /* Motorola FFP math routines */
- long SPFix(), SPCmp(), SPTst();
- float SPFlt(), SPNeg(), SPAdd(), SPSub(), SPMul(), SPDiv();
- float SPSincos(), SPAcos(), SPSqrt();
-
- /* information for display and graphics */
- #define WIDTH 656L
- #define HEIGHT 430L
- #define PLANES 3
- #define PLANESIZE (long)((WIDTH>>3)*HEIGHT)
-
- struct Screen *screen, *OpenScreen();
- struct ViewPort *vp;
- struct Window *window, *OpenWindow();
- struct RastPort *rp;
- struct IntuiMessage *_GetMsg();
- PLANEPTR buffer1[PLANES], buffer2[PLANES];
-
- struct NewScreen MyScreen = {
- 0,0, WIDTH,HEIGHT,PLANES, 0,1, HIRES|LACE,CUSTOMSCREEN,
- NULL,(UBYTE *)"4D Navigator",NULL,NULL
- };
-
- struct NewWindow MyWindow = {
- 0,0, WIDTH,HEIGHT, 0,1, RAWKEY,
- NOCAREREFRESH|BORDERLESS|ACTIVATE|SIMPLE_REFRESH|RMBTRAP,
- NULL,NULL,NULL,NULL,NULL, WIDTH,HEIGHT, WIDTH,HEIGHT, CUSTOMSCREEN
- };
-
- /* colors */
- #define BLACK 0L
- #define WHITE 7L
-
- UWORD ColorTables[3][1<<PLANES] = {
- /* B/W RED GREEN R+G BLUE R+B G+B W/B */
- {0x0000,0x0A00,0x0070,0x0A90,0x000A,0x0B0A,0x0079,0x0CCC},
- {0x0FFF,0x0F00,0x00C0,0x0F90,0x000F,0x0C0E,0x00BA,0x0000},
- /* used by color requester */
- {0x0000,0x0A00,0x0070,0x0A90,0x000A,0x0B0A,0x0079,0x0CCC}
- };
-
- /* arrays for holding pre-computed, converted "floating point" values */
- short *cos, *sin, *factor, *_AllocMem();
-
- /* arrays for holding the "GRID" */
- short *p4d, *e4d, *x4d, *p3d, *e3d, *x3d, *p2d, *e2d, *x2d;
- /* indexing macro for grid points */
- #define INDX(i,j,k) (((((i)*LATRNG)+(j))*SEGMENTS)+(k))
-
- /* view parameters */
- short FrontLimit = 0, BackLimit = 15000, ScaleFactor = 30;
-
- /* point is out of range */
- #define DONT_PLOT 32000
- #asm
- NO_PLOT equ 32000
- #endasm
-
-
- /* sets up the pre-computed, converted "floating point" arrays */
- Initialize()
- {
- register long i;
- register float tsin;
- float tcos;
- register float w;
- register short *x, *y;
-
- Countdown();
- x = cos; y = sin;
- for (i=0; i<720; i++) {
- tsin = SPSincos(&tcos,SPMul(HALF_DEG,SPFlt(i)));
- *(x++) = (SPTst(tcos) >= 0) ? SPFix(SPAdd(0.5,SPMul(tcos,8192.0))) :
- SPFix(SPSub(0.5,SPMul(tcos,8192.0)));
- *(y++) = (SPTst(tsin) >= 0) ? SPFix(SPAdd(0.5,SPMul(tsin,8192.0))) :
- SPFix(SPSub(0.5,SPMul(tsin,8192.0)));
- }
-
- Countdown();
- x = factor+1;
- for (i=-8191; i<=8191; i++) {
- if (!(i&0x000001FF)) Countdown();
- w = SPDiv(8192.0,SPFlt(i));
- *(x++) = SPFix(SPAdd(SPMul(SPDiv(SPSqrt(SPSub(SPMul(w,w),1.0)),
- SPAcos(w)),128.0),0.5));
- }
- Countdown();
- }
-
-
- /* sets the "GRID" to the "starting position" */
- initial_pos()
- {
- short plong,lat,elong;
- register short regd4, regd5;
- long ind;
- register long ind1,ind2;
- register short *pts = x4d;
-
- ind = 0;
- for (plong=0; plong<180; plong+=INTERVAL) {
- e4d[ind+X] = p4d[ind+Z] = sin[plong*2];
- e4d[ind+W] = p4d[ind+Y] = cos[plong*2];
- e4d[ind+Y] = e4d[ind+Z] = p4d[ind+X] = p4d[ind+W] = 0;
- e4d[ind+(ONE80*4+X)] = p4d[ind+(ONE80*4+Z)] = sin[(plong+180)*2];
- e4d[ind+(ONE80*4+W)] = p4d[ind+(ONE80*4+Y)] = cos[(plong+180)*2];
- e4d[ind+(ONE80*4+Y)] = e4d[ind+(ONE80*4+Z)] =
- p4d[ind+(ONE80*4+X)] = p4d[ind+(ONE80*4+W)] = 0;
- ind += 4;
- for (lat=INTERVAL; lat<=(90-INTERVAL); lat+=INTERVAL) {
- ind1 = INDX(plong/INTERVAL,(lat/INTERVAL)-1,0)*4;
- ind2 = INDX((plong/INTERVAL)+ONE80,(lat/INTERVAL)-1,ONE80)*4;
- for (elong=0; elong<180; elong+=INTERVAL) {
-
- regd4 = cos[lat*2]; regd5 = sin[plong*2];
- #asm
- muls d4,d5
- moveq #13,d4
- asr.l d4,d5
- #endasm
- pts[ind1+X] = regd5; regd5 = (-regd5); pts[ind2+X] = regd5;
-
- regd4 = sin[lat*2]; regd5 = cos[elong*2];
- #asm
- muls d4,d5
- moveq #13,d4
- asr.l d4,d5
- #endasm
- pts[ind1+Y] = regd5; regd5 = (-regd5); pts[ind2+Y] = regd5;
-
- regd4 = sin[lat*2]; regd5 = sin[elong*2];
- #asm
- muls d4,d5
- moveq #13,d4
- asr.l d4,d5
- #endasm
- pts[ind1+Z] = regd5; regd5 = (-regd5); pts[ind2+Z] = regd5;
-
- regd4 = cos[lat*2]; regd5 = cos[plong*2];
- #asm
- muls d4,d5
- moveq #13,d4
- asr.l d4,d5
- #endasm
- pts[ind1+W] = regd5; regd5 = (-regd5); pts[ind2+W] = regd5;
-
- ind1+=4; ind2+=4;
- }
- ind1 = INDX(plong/INTERVAL,(lat/INTERVAL)-1,ONE80)*4;
- ind2 = INDX((plong/INTERVAL)+ONE80,(lat/INTERVAL)-1,0)*4;
- for (elong=180; elong<360; elong+=INTERVAL) {
-
- regd4 = cos[lat*2]; regd5 = sin[plong*2];
- #asm
- muls d4,d5
- moveq #13,d4
- asr.l d4,d5
- #endasm
- pts[ind1+X] = regd5; regd5 = (-regd5); pts[ind2+X] = regd5;
-
- regd4 = sin[lat*2]; regd5 = cos[elong*2];
- #asm
- muls d4,d5
- moveq #13,d4
- asr.l d4,d5
- #endasm
- pts[ind1+Y] = regd5; regd5 = (-regd5); pts[ind2+Y] = regd5;
-
- regd4 = sin[lat*2]; regd5 = sin[elong*2];
- #asm
- muls d4,d5
- moveq #13,d4
- asr.l d4,d5
- #endasm
- pts[ind1+Z] = regd5; regd5 = (-regd5); pts[ind2+Z] = regd5;
-
- regd4 = cos[lat*2]; regd5 = cos[plong*2];
- #asm
- muls d4,d5
- moveq #13,d4
- asr.l d4,d5
- #endasm
- pts[ind1+W] = regd5; regd5 = (-regd5); pts[ind2+W] = regd5;
-
- ind1+=4; ind2+=4;
- }
- }
- }
- }
-
-
- /* rotates the four-dimensional space */
- rotate_4d(dir1,dir2,angle)
- long dir1, dir2;
- short angle;
- {
- short plong,lat,elong;
- register short regd4, regd5, cangle, sangle;
- short *p4d11, *p4d12, *p4d21, *p4d22;
- short *e4d11, *e4d12, *e4d21, *e4d22;
- register short *x4d11, *x4d12;
- short *x4d21, *x4d22;
-
- if (angle == RESTART) {
- initial_pos();
- return;
- }
-
- cangle = cos[angle]; sangle = sin[angle];
-
- p4d11 = p4d + dir1;
- p4d12 = p4d + dir2;
- p4d21 = p4d + ONE80*4 + dir1;
- p4d22 = p4d + ONE80*4 + dir2;
-
- e4d11 = e4d + dir1;
- e4d12 = e4d + dir2;
- e4d21 = e4d + ONE80*4 + dir1;
- e4d22 = e4d + ONE80*4 + dir2;
-
- x4d11 = x4d + dir1;
- x4d12 = x4d + dir2;
- x4d21 = x4d + INDX(ONE80,0,-ONE80)*4 + dir1;
- x4d22 = x4d + INDX(ONE80,0,-ONE80)*4 + dir2;
-
- for (plong=0; plong++ < ONE80; ) {
- regd4 = *p4d11; regd5 = *p4d12;
- #asm
- move.w d4,d0 ; d1' = d1*cos - d2*sin
- muls d6,d0
- move.w d5,d2
- muls d7,d2
- sub.l d2,d0
- move.w d4,d1 ; d2' = d1*sin + d2*cos
- muls d7,d1
- move.w d5,d2
- muls d6,d2
- add.l d2,d1
- moveq #13,d3 ; normalize
- asr.l d3,d0
- asr.l d3,d1
- move.w d0,d4
- move.w d1,d5
- #endasm
- *p4d11 = regd4; regd4 = (-regd4); *p4d21 = regd4;
- *p4d12 = regd5; regd5 = (-regd5); *p4d22 = regd5;
- p4d11+=4; p4d12+=4; p4d21+=4; p4d22+=4;
-
- regd4 = *e4d11; regd5 = *e4d12;
- #asm
- move.w d4,d0
- muls d6,d0
- move.w d5,d2
- muls d7,d2
- sub.l d2,d0
- move.w d4,d1
- muls d7,d1
- move.w d5,d2
- muls d6,d2
- add.l d2,d1
- moveq #13,d3
- asr.l d3,d0
- asr.l d3,d1
- move.w d0,d4
- move.w d1,d5
- #endasm
- *e4d11 = regd4; regd4 = (-regd4); *e4d21 = regd4;
- *e4d12 = regd5; regd5 = (-regd5); *e4d22 = regd5;
- e4d11+=4; e4d12+=4; e4d21+=4; e4d22+=4;
-
- for (lat=0; lat++ < LATRNG; ) {
- x4d21 += (SEGMENTS*4); x4d22 += (SEGMENTS*4);
- for (elong=0; elong++ < ONE80; ) {
- regd4 = *x4d11; regd5 = *x4d12;
- #asm
- move.w d4,d0
- muls d6,d0
- move.w d5,d2
- muls d7,d2
- sub.l d2,d0
- move.w d4,d1
- muls d7,d1
- move.w d5,d2
- muls d6,d2
- add.l d2,d1
- moveq #13,d3
- asr.l d3,d0
- asr.l d3,d1
- move.w d0,d4
- move.w d1,d5
- #endasm
- *x4d11 = regd4; regd4 = (-regd4); *x4d21 = regd4;
- *x4d12 = regd5; regd5 = (-regd5); *x4d22 = regd5;
- x4d11+=4; x4d12+=4; x4d21+=4; x4d22+=4;
- }
-
- x4d21 -= (SEGMENTS*4); x4d22 -= (SEGMENTS*4);
- for (elong=ONE80; elong++ < SEGMENTS; ) {
- regd4 = *x4d11; regd5 = *x4d12;
- #asm
- move.w d4,d0
- muls d6,d0
- move.w d5,d2
- muls d7,d2
- sub.l d2,d0
- move.w d4,d1
- muls d7,d1
- move.w d5,d2
- muls d6,d2
- add.l d2,d1
- moveq #13,d3
- asr.l d3,d0
- asr.l d3,d1
- move.w d0,d4
- move.w d1,d5
- #endasm
- *x4d11 = regd4; regd4 = (-regd4); *x4d21 = regd4;
- *x4d12 = regd5; regd5 = (-regd5); *x4d22 = regd5;
- x4d11+=4; x4d12+=4; x4d21+=4; x4d22+=4;
- }
- }
- }
- }
-
-
- /* maps the four-dimensional space into three dimensions */
- map_to_3d()
- {
- register short regd4, regd5, regd6, regd7;
- short wval;
- short plong,lat,elong;
- short *p4d1, *p3d1, *p3d2;
- short *e4d1, *e3d1, *e3d2;
- register short *x4d1;
- short *x3d1;
- register short *x3d2;
-
- p4d1 = p4d; p3d1 = p3d; p3d2 = p3d + ONE80*3;
- e4d1 = e4d; e3d1 = e3d; e3d2 = e3d + ONE80*3;
- x4d1 = x4d; x3d1 = x3d; x3d2 = x3d + INDX(ONE80,0,-ONE80)*3;
-
- for (plong=0; plong++ < ONE80; ) {
- if ((wval = *(p4d1+W)) >= 8192) {
- *(p4d1+W) = 8192;
- *(p3d1+X) = *(p4d1+X); *(p3d1+Y) = *(p4d1+Y); *(p3d1+Z) = *(p4d1+Z);
- *(p4d1+ONE80*4+W) = -8192;
- *(p3d2+X) = DONT_PLOT; *(p3d2+Y) = *(p3d2+Z) = 0;
- } else
- if (wval <= -8192) {
- *(p4d1+W) = -8192;
- *(p3d1+X) = DONT_PLOT; *(p3d1+Y) = *(p3d1+Z) = 0;
- *(p4d1+ONE80*4+W) = 8192;
- *(p3d2+X) = (-(*(p4d1+X))); *(p3d2+Y) = (-(*(p4d1+Y)));
- *(p3d2+Z) = (-(*(p4d1+Z)));
- } else {
- regd6 = factor[8192+wval]; regd7 = factor[8192-wval];
-
- regd4 = *(p4d1+X);
- #asm
- dummy1: move.w d4,d5
- neg.w d5
- cmpi.w #1000,d6
- blt.s 1$
- move.w #NO_PLOT,d4
- bra.s 2$
- 1$ muls d6,d4
- asr.l #7,d4
- cmpi.w #1000,d7
- blt.s 2$
- move.w #NO_PLOT,d5
- bra.s 3$
- 2$ muls d7,d5
- asr.l #7,d5
- 3$
- #endasm
- *(p3d1+X) = regd4; *(p3d2+X) = regd5;
-
- regd4 = *(p4d1+Y);
- #asm
- move.w d4,d5
- neg.w d5
- muls d6,d4
- muls d7,d5
- asr.l #7,d4
- asr.l #7,d5
- #endasm
- *(p3d1+Y) = regd4; *(p3d2+Y) = regd5;
-
- regd4 = *(p4d1+Z);
- #asm
- move.w d4,d5
- neg.w d5
- muls d6,d4
- muls d7,d5
- asr.l #7,d4
- asr.l #7,d5
- #endasm
- *(p3d1+Z) = regd4; *(p3d2+Z) = regd5;
- }
- p4d1+=4; p3d1+=3; p3d2+=3;
-
- if ((wval = *(e4d1+W)) >= 8192) {
- *(e4d1+W) = 8192;
- *(e3d1+X) = *(e4d1+X); *(e3d1+Y) = *(e4d1+Y); *(e3d1+Z) = *(e4d1+Z);
- *(e4d1+ONE80*4+W) = -8192;
- *(e3d2+X) = DONT_PLOT; *(e3d2+Y) = *(e3d2+Z) = 0;
- } else
- if (wval <= -8192) {
- *(e4d1+W) = -8192;
- *(e3d1+X) = DONT_PLOT; *(e3d1+Y) = *(e3d1+Z) = 0;
- *(e4d1+ONE80*4+W) = 8192;
- *(e3d2+X) = (-(*(e4d1+X))); *(e3d2+Y) = (-(*(e4d1+Y)));
- *(e3d2+Z) = (-(*(e4d1+Z)));
- } else {
- regd6 = factor[8192+wval]; regd7 = factor[8192-wval];
-
- regd4 = *(e4d1+X);
- #asm
- dummy2: move.w d4,d5
- neg.w d5
- cmpi.w #1000,d6
- blt.s 1$
- move.w #NO_PLOT,d4
- bra.s 2$
- 1$ muls d6,d4
- asr.l #7,d4
- cmpi.w #1000,d7
- blt.s 2$
- move.w #NO_PLOT,d5
- bra.s 3$
- 2$ muls d7,d5
- asr.l #7,d5
- 3$
- #endasm
- *(e3d1+X) = regd4; *(e3d2+X) = regd5;
-
- regd4 = *(e4d1+Y);
- #asm
- move.w d4,d5
- neg.w d5
- muls d6,d4
- muls d7,d5
- asr.l #7,d4
- asr.l #7,d5
- #endasm
- *(e3d1+Y) = regd4; *(e3d2+Y) = regd5;
-
- regd4 = *(e4d1+Z);
- #asm
- move.w d4,d5
- neg.w d5
- muls d6,d4
- muls d7,d5
- asr.l #7,d4
- asr.l #7,d5
- #endasm
- *(e3d1+Z) = regd4; *(e3d2+Z) = regd5;
- }
- e4d1+=4; e3d1+=3; e3d2+=3;
-
- for (lat=0; lat++ < LATRNG; ) {
- x3d2 += (SEGMENTS*3);
- for (elong=0; elong++ < ONE80; ) {
- if ((wval = *(x4d1+W)) >= 8192) {
- *(x4d1+W) = 8192;
- *(x3d1+X) = *(x4d1+X); *(x3d1+Y) = *(x4d1+Y); *(x3d1+Z) = *(x4d1+Z);
- *(x4d1+INDX(ONE80,0,ONE80)*4+W) = -8192;
- *(x3d2+X) = DONT_PLOT; *(x3d2+Y) = *(x3d2+Z) = 0;
- } else
- if (wval <= -8192) {
- *(x4d1+W) = -8192;
- *(x3d1+X) = DONT_PLOT; *(x3d1+Y) = *(x3d1+Z) = 0;
- *(x4d1+INDX(ONE80,0,ONE80)*4+W) = 8192;
- *(x3d2+X) = (-(*(x4d1+X))); *(x3d2+Y) = (-(*(x4d1+Y)));
- *(x3d2+Z) = (-(*(x4d1+Z)));
- } else {
- regd6 = factor[8192+wval]; regd7 = factor[8192-wval];
-
- regd4 = *(x4d1+X);
- #asm
- dummy3: move.w d4,d5
- neg.w d5
- cmpi.w #1000,d6
- blt.s 1$
- move.w #NO_PLOT,d4
- bra.s 2$
- 1$ muls d6,d4
- asr.l #7,d4
- cmpi.w #1000,d7
- blt.s 2$
- move.w #NO_PLOT,d5
- bra.s 3$
- 2$ muls d7,d5
- asr.l #7,d5
- 3$
- #endasm
- *(x3d1+X) = regd4; *(x3d2+X) = regd5;
-
- regd4 = *(x4d1+Y);
- #asm
- move.w d4,d5
- neg.w d5
- muls d6,d4
- muls d7,d5
- asr.l #7,d4
- asr.l #7,d5
- #endasm
- *(x3d1+Y) = regd4; *(x3d2+Y) = regd5;
-
- regd4 = *(x4d1+Z);
- #asm
- move.w d4,d5
- neg.w d5
- muls d6,d4
- muls d7,d5
- asr.l #7,d4
- asr.l #7,d5
- #endasm
- *(x3d1+Z) = regd4; *(x3d2+Z) = regd5;
- }
- x4d1+=4; x3d1+=3; x3d2+=3;
- }
- x3d2 -= (SEGMENTS*3);
- for (elong=ONE80; elong++ < SEGMENTS; ) {
- if ((wval = *(x4d1+W)) >= 8192) {
- *(x4d1+W) = 8192;
- *(x3d1+X) = *(x4d1+X); *(x3d1+Y) = *(x4d1+Y); *(x3d1+Z) = *(x4d1+Z);
- *(x4d1+INDX(ONE80,0,-ONE80)*4+W) = -8192;
- *(x3d2+X) = DONT_PLOT; *(x3d2+Y) = *(x3d2+Z) = 0;
- } else
- if (wval <= -8192) {
- *(x4d1+W) = -8192;
- *(x3d1+X) = DONT_PLOT; *(x3d1+Y) = *(x3d1+Z) = 0;
- *(x4d1+INDX(ONE80,0,-ONE80)*4+W) = 8192;
- *(x3d2+X) = (-(*(x4d1+X))); *(x3d2+Y) = (-(*(x4d1+Y)));
- *(x3d2+Z) = (-(*(x4d1+Z)));
- } else {
- regd6 = factor[8192+wval]; regd7 = factor[8192-wval];
-
- regd4 = *(x4d1+X);
- #asm
- dummy4: move.w d4,d5
- neg.w d5
- cmpi.w #1000,d6
- blt.s 1$
- move.w #NO_PLOT,d4
- bra.s 2$
- 1$ muls d6,d4
- asr.l #7,d4
- cmpi.w #1000,d7
- blt.s 2$
- move.w #NO_PLOT,d5
- bra.s 3$
- 2$ muls d7,d5
- asr.l #7,d5
- 3$
- #endasm
- *(x3d1+X) = regd4; *(x3d2+X) = regd5;
-
- regd4 = *(x4d1+Y);
- #asm
- move.w d4,d5
- neg.w d5
- muls d6,d4
- muls d7,d5
- asr.l #7,d4
- asr.l #7,d5
- #endasm
- *(x3d1+Y) = regd4; *(x3d2+Y) = regd5;
-
- regd4 = *(x4d1+Z);
- #asm
- move.w d4,d5
- neg.w d5
- muls d6,d4
- muls d7,d5
- asr.l #7,d4
- asr.l #7,d5
- #endasm
- *(x3d1+Z) = regd4; *(x3d2+Z) = regd5;
- }
- x4d1+=4; x3d1+=3; x3d2+=3;
- }
- }
- }
- }
-
-
- /* maps the 3D space into coordinates for the screen */
- map_to_screen()
- {
- register short scale = (-ScaleFactor), back = BackLimit, front = FrontLimit, temp;
- short plong, lat, elong;
- short *p3d1, *p2d1, *e3d1, *e2d1;
- register short *x3d1, *x2d1;
-
- p3d1 = p3d; p2d1 = p2d; e3d1 = e3d; e2d1 = e2d; x3d1 = x3d; x2d1 = x2d;
-
- for (plong=0; plong++ < SEGMENTS; ) {
- if ((temp=*(p3d1+X)) < front || temp > back)
- *(p2d1+X) = DONT_PLOT;
- else {
- *(p2d1+X) = (WIDTH/2) + (*(p3d1+Y)/scale);
- temp = *(p3d1+Z);
- #asm
- muls #7,d7 ; for aspect ratio
- asr.l #3,d7
- divs d4,d7 ; *(p2d1+Y) = (HEIGHT/2) + (*(p3d1+Z)/scale);
- add.w #215,d7
- #endasm
- *(p2d1+Y) = temp;
- }
- p3d1+=3; p2d1+=2;
-
- if ((temp=*(e3d1+X)) < front || temp > back)
- *(e2d1+X) = DONT_PLOT;
- else {
- *(e2d1+X) = (WIDTH/2) + (*(e3d1+Y)/scale);
- temp = *(e3d1+Z);
- #asm
- muls #7,d7 ; for aspect ratio
- asr.l #3,d7
- divs d4,d7 ; *(e2d1+Y) = (HEIGHT/2) + (*(e3d1+Z)/scale);
- add.w #215,d7
- #endasm
- *(e2d1+Y) = temp;
- }
- e3d1+=3; e2d1+=2;
-
- for (lat=0; lat++ < LATRNG; ) {
- for (elong=0; elong++ < SEGMENTS; ) {
- if ((temp=*(x3d1+X)) < front || temp > back)
- *(x2d1+X) = DONT_PLOT;
- else {
- *(x2d1+X) = (WIDTH/2) + (*(x3d1+Y)/scale);
- temp = *(x3d1+Z);
- #asm
- muls #7,d7 ; for aspect ratio
- asr.l #3,d7
- divs d4,d7 ; *(x2d1+Y) = (HEIGHT/2) + (*(x3d1+Z)/scale);
- add.w #215,d7
- #endasm
- *(x2d1+Y) = temp;
- }
- x3d1+=3; x2d1+=2;
- }
- }
- }
- }
-
-
- #define LEFT 1
- #define RIGHT 2
- #define TOP 4
- #define BOTTOM 8
-
- /* plots the "GRID" into the screen buffer */
- plot_in_buffer()
- {
- short i, plong, lat, elong;
- long index;
- register long num;
- short firstx, firsty, farfirst;
- register short x, y;
- short far1;
- register short far2=0;
- register short *toplot, *toget;
- short plot_buf[(SEGMENTS+1)*2];
-
- toplot = plot_buf;
- SetBuffer();
-
- /*** EQUATOR & POLAR RING ***/
- for (i=0; i<2; i++) {
- toget = (i==0) ? e2d: p2d;
- num = 0; far1 = 0;
- if ((firstx = toget[0]) != DONT_PLOT) {
- toplot[0] = firstx; toplot[1] = firsty = toget[1]; num = 2;
- if (firstx < 0)
- far1 |= LEFT;
- else if (firstx >= WIDTH)
- far1 |= RIGHT;
- if (firsty < 0)
- far1 |= TOP;
- else if (firsty >= HEIGHT)
- far1 |= BOTTOM;
- farfirst = far1;
- }
- for (elong=2; elong<SEGMENTS*2; elong+=2) {
- if ((x = toget[elong]) != DONT_PLOT) {
- y = toget[elong+1];
- if (x < 0)
- far2 |= LEFT;
- else if (x >= WIDTH)
- far2 |= RIGHT;
- if (y < 0)
- far2 |= TOP;
- else if (y >= HEIGHT)
- far2 |= BOTTOM;
- if (far1 & far2) {
- if (num >= 4) {
- Move(rp,(long)toplot[0],(long)toplot[1]);
- PolyDraw(rp,num>>1,toplot);
- num = 2;
- }
- toplot[0] = x;
- toplot[1] = y;
- } else {
- toplot[num++] = x;
- toplot[num++] = y;
- }
- far1 = far2; far2 = 0;
- } else {
- if (num >= 4) {
- Move(rp,(long)toplot[0],(long)toplot[1]);
- PolyDraw(rp,num>>1,toplot);
- }
- num = 0; far1 = 0;
- }
- }
- if (num >= 2) {
- if (firstx != DONT_PLOT) {
- if (!(far1 & farfirst)) {
- toplot[num++] = firstx; toplot[num++] = firsty;
- }
- }
- if (num >= 4) {
- Move(rp,(long)toplot[0],(long)toplot[1]);
- PolyDraw(rp,num>>1,toplot);
- }
- }
- }
-
- toget = x2d;
-
- /*** CIRCUM-EQUATORIAL ***/
- rp->Mask = 0xFC;
- for (lat=0; lat<LATRNG; lat++) {
- for (elong=0; elong<SEGMENTS; elong++) {
- num = 0; far1 = 0;
- index=INDX(0,lat,elong)*2;
- if ((firstx = toget[index]) != DONT_PLOT) {
- toplot[0] = firstx; toplot[1] = firsty = toget[index+1]; num = 2;
- if (firstx < 0)
- far1 |= LEFT;
- else if (firstx >= WIDTH)
- far1 |= RIGHT;
- if (firsty < 0)
- far1 |= TOP;
- else if (firsty >= HEIGHT)
- far1 |= BOTTOM;
- farfirst = far1;
- }
- for (plong=2; plong<SEGMENTS*2; plong+=2) {
- index += LATRNG*SEGMENTS*2;
- if ((x = toget[index]) != DONT_PLOT) {
- y = toget[index+1];
- if (x < 0)
- far2 |= LEFT;
- else if (x >= WIDTH)
- far2 |= RIGHT;
- if (y < 0)
- far2 |= TOP;
- else if (y >= HEIGHT)
- far2 |= BOTTOM;
- if (far1 & far2) {
- if (num >= 4) {
- Move(rp,(long)toplot[0],(long)toplot[1]);
- PolyDraw(rp,num>>1,toplot);
- num = 2;
- }
- toplot[0] = x;
- toplot[1] = y;
- } else {
- toplot[num++] = x;
- toplot[num++] = y;
- }
- far1 = far2; far2 = 0;
- } else {
- if (num >= 4) {
- Move(rp,(long)toplot[0],(long)toplot[1]);
- PolyDraw(rp,num>>1,toplot);
- }
- num = 0; far1 = 0;
- }
- }
- if (num >= 2) {
- if (firstx != DONT_PLOT) {
- if (!(far1 & farfirst)) {
- toplot[num++] = firstx; toplot[num++] = firsty;
- }
- }
- if (num >= 4) {
- Move(rp,(long)toplot[0],(long)toplot[1]);
- PolyDraw(rp,num>>1,toplot);
- }
- }
- }
- }
-
- /*** CIRCUM-POLAR ***/
- rp->Mask = 0xF9;
- for (lat=0; lat<LATRNG; lat++) {
- for (plong=0; plong<SEGMENTS; plong++) {
- num = 0; far1 = 0;
- index=INDX(plong,lat,0)*2;
- if ((firstx = toget[index]) != DONT_PLOT) {
- toplot[0] = firstx; toplot[1] = firsty = toget[index+1]; num = 2;
- if (firstx < 0)
- far1 |= LEFT;
- else if (firstx >= WIDTH)
- far1 |= RIGHT;
- if (firsty < 0)
- far1 |= TOP;
- else if (firsty >= HEIGHT)
- far1 |= BOTTOM;
- farfirst = far1;
- }
- for (elong=2; elong<SEGMENTS*2; elong+=2) {
- index += 2;
- if ((x = toget[index]) != DONT_PLOT) {
- y = toget[index+1];
- if (x < 0)
- far2 |= LEFT;
- else if (x >= WIDTH)
- far2 |= RIGHT;
- if (y < 0)
- far2 |= TOP;
- else if (y >= HEIGHT)
- far2 |= BOTTOM;
- if (far1 & far2) {
- if (num >= 4) {
- Move(rp,(long)toplot[0],(long)toplot[1]);
- PolyDraw(rp,num>>1,toplot);
- num = 2;
- }
- toplot[0] = x;
- toplot[1] = y;
- } else {
- toplot[num++] = x;
- toplot[num++] = y;
- }
- far1 = far2; far2 = 0;
- } else {
- if (num >= 4) {
- Move(rp,(long)toplot[0],(long)toplot[1]);
- PolyDraw(rp,num>>1,toplot);
- }
- num = 0; far1 = 0;
- }
- }
- if (num >= 2) {
- if (firstx != DONT_PLOT) {
- if (!(far1 & farfirst)) {
- toplot[num++] = firstx; toplot[num++] = firsty;
- }
- }
- if (num >= 4) {
- Move(rp,(long)toplot[0],(long)toplot[1]);
- PolyDraw(rp,num>>1,toplot);
- }
- }
- }
- }
-
- /*** LONG LINES ***/
- rp->Mask = 0xFA;
- for (elong=0; elong<SEGMENTS; elong++) {
- for (plong=0; plong<SEGMENTS; plong++) {
- num = 0; far1 = 0;
- if (!(elong&1))
- if ((x = e2d[plong*2]) != DONT_PLOT) {
- toplot[0] = x; y = toplot[1] = e2d[plong*2+1]; num=2;
- if (x < 0)
- far1 |= LEFT;
- else if (x >= WIDTH)
- far1 |= RIGHT;
- if (y < 0)
- far1 |= TOP;
- else if (y >= HEIGHT)
- far1 |= BOTTOM;
- }
- index=INDX(plong,0,elong)*2;
- for (lat=0; lat<LATRNG; lat++) {
- if ((x = toget[index]) != DONT_PLOT) {
- y = toget[index+1];
- if (x < 0)
- far2 |= LEFT;
- else if (x >= WIDTH)
- far2 |= RIGHT;
- if (y < 0)
- far2 |= TOP;
- else if (y >= HEIGHT)
- far2 |= BOTTOM;
- if (far1 & far2) {
- if (num >= 4) {
- Move(rp,(long)toplot[0],(long)toplot[1]);
- PolyDraw(rp,num>>1,toplot);
- num = 2;
- }
- toplot[0] = x;
- toplot[1] = y;
- } else {
- toplot[num++] = x;
- toplot[num++] = y;
- }
- far1 = far2; far2 = 0;
- } else {
- if (num >= 4) {
- Move(rp,(long)toplot[0],(long)toplot[1]);
- PolyDraw(rp,num>>1,toplot);
- }
- num = 0; far1 = 0;
- }
- index += SEGMENTS*2;
- }
- if (num >= 2) {
- if (!(plong&1))
- if ((x = p2d[elong*2]) != DONT_PLOT) {
- y = p2d[elong*2+1];
- if (x < 0)
- far2 |= LEFT;
- else if (x >= WIDTH)
- far2 |= RIGHT;
- if (y < 0)
- far2 |= TOP;
- else if (y >= HEIGHT)
- far2 |= BOTTOM;
- if (!(far1 & far2)) {
- toplot[num++] = x; toplot[num++] = y;
- }
- far2 = 0;
- }
- if (num >= 4) {
- Move(rp,(long)toplot[0],(long)toplot[1]);
- PolyDraw(rp,num>>1,toplot);
- }
- }
- }
- }
- rp->Mask = 0xFF;
- DisplayBuffer();
- }
-
-
- /* for double buffering */
- SetBuffer()
- {
- register long i;
-
- if (rp->BitMap->Planes[0] == buffer1[0])
- for (i=0; i<PLANES; i++)
- rp->BitMap->Planes[i] = buffer2[i];
- else
- for (i=0; i<PLANES; i++)
- rp->BitMap->Planes[i] = buffer1[i];
- SetRast(rp,BLACK);
- }
-
-
- DisplayBuffer()
- {
- WaitBOVP(vp);
- WaitTOF();
- ScrollVPort(vp);
- RethinkDisplay();
- }
-
-
- #define ONE_KEY 1
- #define ZERO_KEY 10
- #define ESCAPE 69
- #define SPACE 64
- #define RKEY 19
- #define TKEY 20
- #define XKEY 50
- #define CKEY 51
- #define VKEY 52
- #define KP8 62
- #define KP2 30
- #define KP4 45
- #define KP6 47
- #define LEFTARROW 79
- #define RIGHTARROW 78
- #define UPARROW 76
- #define DOWNARROW 77
- #define HELP 95
- #if DEBUG
- #define DKEY 34
- #endif
-
- #define TRANSLATE 1
- #define ROTATE 0
-
- MainLoop()
- {
- register struct IntuiMessage *msg;
- register ULONG class;
- register USHORT code, qualifier;
- short mode, amount, step_rate;
- long fromdir, toward;
- short ColorSet = BLACK;
- #if TIMING
- long starttime[3],endtime[3];
- #endif
-
- Initialize();
- mode = TRANSLATE; fromdir = X; toward = W; amount = RESTART, step_rate = 10;
-
- FOREVER {
- if (amount == STOPPED) {
- _WaitPort(window->UserPort);
- } else {
-
- #if TIMING
- DateStamp(starttime);
- #endif
- rotate_4d(fromdir,toward,amount);
- map_to_3d();
- map_to_screen();
- plot_in_buffer();
- #if TIMING
- DateStamp(endtime);
- PrintTime("Frame time",starttime,endtime);
- #endif
- if (amount != step_rate && amount != THREE_SIXTY-step_rate)
- amount = STOPPED;
- }
- while (msg = _GetMsg(window->UserPort)) {
- class = msg->Class; code = msg->Code; qualifier = msg->Qualifier;
- _ReplyMsg(msg);
- if (class == RAWKEY) {
- switch (code) {
- #if DEBUG
- case DKEY:
- if (qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
- dump_coordinates(0); /* only plotted points */
- else if (qualifier & (IEQUALIFIER_LALT|IEQUALIFIER_RALT))
- dump_coordinates(1); /* all points */
- else
- dump_screen_plot();
- break;
- #endif
- case RKEY:
- case TKEY:
- mode = (code == TKEY);
- break;
- case XKEY:
- mode = TRANSLATE; fromdir = X; toward = W; amount = RESTART;
- break;
- case CKEY:
- if (qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)) {
- ColorRequester(ColorSet);
- if (amount == STOPPED) plot_in_buffer();
- } else {
- ColorSet = 1 - ColorSet;
- LoadRGB4(vp, &ColorTables[ColorSet][0], 1L<<PLANES);
- }
- break;
- case VKEY:
- ViewRequester();
- if (amount == STOPPED) {
- map_to_screen();
- plot_in_buffer();
- }
- break;
- case SPACE: amount = STOPPED; break;
- case KP4:
- case KP6:
- fromdir = Y; toward = (mode) ? W : X;
- goto calc_amount;
- case KP8:
- case KP2:
- fromdir = Z; toward = (mode) ? W : X;
- goto calc_amount;
- case LEFTARROW:
- case RIGHTARROW:
- mode = ROTATE; fromdir = Z; toward = Y;
- goto calc_amount;
- case UPARROW:
- case DOWNARROW:
- mode = TRANSLATE; fromdir = X; toward = W;
- calc_amount:
- if (qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
- amount = TEN_DEGREES;
- else if (qualifier & IEQUALIFIER_CONTROL)
- amount = NINETY_DEGREES;
- else
- amount = step_rate;
- if (code == KP2 || code == LEFTARROW ||
- code == KP6 || code == DOWNARROW)
- amount = THREE_SIXTY - amount;
- break;
- case ESCAPE:
- cleanup(0L);
- case HELP:
- LoadRGB4(vp, &ColorTables[0][0], 1L<<PLANES);
- info();
- LoadRGB4(vp, &ColorTables[ColorSet][0], 1L<<PLANES);
- if (amount == STOPPED) plot_in_buffer();
- break;
- default:
- if (code >= ONE_KEY && code <= ZERO_KEY) {
- if (amount != STOPPED)
- if (amount == step_rate)
- amount = code;
- else
- amount = THREE_SIXTY - code;
- step_rate = code;
- }
- }
- }
- }
- }
- }
-
-
- main()
- {
- long i;
-
- if (IntuitionBase = _OpenLibrary("intuition.library", 0L))
- if (GfxBase = _OpenLibrary("graphics.library", 0L))
- if (MathBase = _OpenLibrary("mathffp.library", 0L))
- if (MathTransBase = _OpenLibrary("mathtrans.library", 0L))
- if (p4d = _AllocMem((long)(SEGMENTS*8),0L))
- if (e4d = _AllocMem((long)(SEGMENTS*8),0L))
- if (x4d = _AllocMem((long)(NUM_GRID_PTS*8L),0L))
- if (p3d = _AllocMem((long)(SEGMENTS*6),0L))
- if (e3d = _AllocMem((long)(SEGMENTS*6),0L))
- if (x3d = _AllocMem((long)(NUM_GRID_PTS*6L),0L))
- if (p2d = _AllocMem((long)(SEGMENTS*4),0L))
- if (e2d = _AllocMem((long)(SEGMENTS*4),0L))
- if (x2d = _AllocMem((long)(NUM_GRID_PTS*4L),0L))
- if (cos = _AllocMem(1440L,0L))
- if (sin = _AllocMem(1440L,0L))
- if (factor = _AllocMem(32768L,0L))
- if (screen = OpenScreen(&MyScreen)) {
- vp = &screen->ViewPort;
- LoadRGB4(vp,&ColorTables[0][0],1L<<PLANES);
- MyWindow.Screen = screen;
- if (window = OpenWindow(&MyWindow)) {
- rp = window->RPort;
- SetDrMd(rp,(long)JAM1);
- SetAPen(rp,WHITE);
- for (i=0; i<PLANES; i++) {
- buffer1[i] = rp->BitMap->Planes[i];
- if (!(buffer2[i] = (PLANEPTR)_AllocMem(PLANESIZE,CLEARED_CHIP)))
- cleanup(101L);
- }
- MainLoop(); /* terminates via cleanup() */
- }
- }
- cleanup(100L); /* no direct indication of what went wrong above */
- }
-
-
- cleanup(code)
- long code;
- {
- long i;
-
- if (p4d) _FreeMem(p4d,(long)(SEGMENTS*8));
- if (e4d) _FreeMem(e4d,(long)(SEGMENTS*8));
- if (x4d) _FreeMem(x4d,(long)(NUM_GRID_PTS*8L));
- if (p3d) _FreeMem(p3d,(long)((long)SEGMENTS*6L));
- if (e3d) _FreeMem(e3d,(long)((long)SEGMENTS*6L));
- if (x3d) _FreeMem(x3d,(long)(NUM_GRID_PTS*6L));
- if (p2d) _FreeMem(p2d,(long)((long)SEGMENTS*4L));
- if (e2d) _FreeMem(e2d,(long)((long)SEGMENTS*4L));
- if (x2d) _FreeMem(x2d,(long)(NUM_GRID_PTS*4L));
- if (cos) _FreeMem(cos,1440L);
- if (sin) _FreeMem(sin,1440L);
- if (factor) _FreeMem(factor,32768L);
- if (window) {
- if (rp->BitMap->Planes[0] == buffer2[0]) {
- SetBuffer();
- DisplayBuffer();
- }
- CloseWindow(window);
- }
- for (i=0; i<PLANES; i++)
- if (buffer2[i]) _FreeMem(buffer2[i],PLANESIZE);
- if (screen) CloseScreen(screen);
- if (MathTransBase) _CloseLibrary(MathTransBase);
- if (MathBase) _CloseLibrary(MathBase);
- if (GfxBase) _CloseLibrary(GfxBase);
- if (IntuitionBase) _CloseLibrary(IntuitionBase);
- exit(code);
- }
-
-
- #define X0 0L
- #define X1 20L
- #define X2 65L
- #define X3 85L
- #define Y0 0L
- #define Y1 20L
- #define Y2 60L
- #define Y3 80L
- #define Y4 120L
- #define Y5 140L
-
- Digit(n,x,y)
- short n;
- long x,y;
- {
- /* first a white rectangle */
- RectFill(rp,x+X0,y+Y0,x+X3,y+Y5);
- /* then "cut out" the appropriate parts */
- SetAPen(rp,BLACK);
- switch (n) {
- case 0: RectFill(rp,x+X1,y+Y1,x+X2,y+Y4); return;
- case 1: RectFill(rp,x+X0,y+Y0,x+X2,y+Y5); return;
- case 2:
- case 3: RectFill(rp,x+X0,y+Y1,x+X2,y+Y2); break; /* upper section */
- case 4: RectFill(rp,x+X1,y+Y0,x+X2,y+Y2);
- RectFill(rp,x+X0,y+Y3,x+X2,y+Y5); return;
- case 5:
- case 6: RectFill(rp,x+X1,y+Y1,x+X3,y+Y2); break; /* upper section */
- case 7: RectFill(rp,x+X0,y+Y1,x+X2,y+Y5); return;
- case 8:
- case 9: RectFill(rp,x+X1,y+Y1,x+X2,y+Y2); /* upper section */
- }
- /* lower sections */
- if (n==2)
- RectFill(rp,x+X1,y+Y3,x+X3,y+Y4);
- else if (n==3 || n==5 || n==9)
- RectFill(rp,x+X0,y+Y3,x+X2,y+Y4);
- else /* n==6 || n==8 */
- RectFill(rp,x+X1,y+Y3,x+X2,y+Y4);
- }
-
-
- #define TENS_X 225L
- #define ONES_X 340L
- #define DIGITY 115L
-
- Countdown()
- {
- static short _counter = 33;
- SetBuffer();
- Digit(_counter/10,TENS_X,DIGITY);
- SetAPen(rp,WHITE);
- Digit(_counter%10,ONES_X,DIGITY);
- SetAPen(rp,WHITE);
- DisplayBuffer();
- _counter--;
- }
-
-
- /*** Info function ***/
-
- struct TextAttr InfoFont =
- {(UBYTE *)"topaz.font",8,FS_NORMAL,FPF_ROMFONT|FPF_DESIGNED};
- struct IntuiText Text = {6,0,JAM2,0,0,&InfoFont,NULL,NULL};
-
- #define TEXT_MARGIN 20L
- #define TEXT_START 25L
-
- char *InfoTitle =
- " 4D Navigator v1.00 \2511991, Jerry D. Hedden, All Rights Reserved";
- char *InfoText[] = {
- "You are embedded within the three-dimensional 'surface' of a four-dimensional",
- "sphere. Your initial position is on the equator looking east. The 'north",
- "pole' of the polar ring is to your left. Pressing 'x' will reset you back to",
- "this initial position. To quit, press 'esc'.",
- "",
- "You can move (translate) or turn (rotate) using the arrow- and keypad keys.",
- "The up/down arrows send you moving forward/backward; the left/right arrows",
- "rotate you clockwise/counterclockwise. The keypad 8, 2, 4 and 6 represent",
- "the up, down, left and right directions. Pressing 't' sets translate mode",
- "such that the keypad moves you in the appropriated directions; 'r' set rotate",
- "mode so you can turn. Pressing an arrow-/keypad key alone causes its action",
- "to repeat continuously. Press 'space' to stop. The change between frames",
- "can be set from 0.5\260 to 5\260 using the keyboard 1 thru 0. 'Shift-' arrow-/",
- "keypad keys cause a single 10\260 change; 'ctrl-' causes a 90\260 change.",
- "",
- "The view of your three-dimensional space is controlled by three parameters --",
- "the scaling factor, the front cutoff, and the rear cutoff. The first con-",
- "trols the width/height of your view; the other two control its depth. Press",
- "'v' to bring up a requester to change these values. N.B. Your view of the",
- "space is mapped to the screen without perspective.",
- "",
- "The coordinate system is: Latitude (LAT) -- the angular distance between the",
- "equator (0\260) and the polar ring (90\260); Polar Longitude (PLONG) -- the angular",
- "direction around the polar ring (0\260 - 360\260); and Equatorial Longitude (ELONG)",
- "-- the angular direction around the equator (0\260 - 360\260). This is an extrap-",
- "olation into three dimensions of latitude and longitude as used on the earth.",
- "",
- "The two white 'circles' are the equator and the polar ring. Green 'longi-",
- "tude' lines run between them -- connecting points with the same PLONG and",
- "ELONG. Red connects points with the same LAT and PLONG, and blue connects",
- "points with the same LAT and ELONG.",
- "",
- "Press 'c' to toggle between two color sets (the 'white' set is intended for",
- "printing). 'Shift-c' brings up a color requester.",
- "",
- "The 4D Navigator source code is a combination of 'C' and assembly using Manx",
- "Aztec 'C' v3.6a. The source contains examples of double-buffering, fixed-",
- "and floating-point math, and in-line assembly code. I also used some of the",
- "code from Jonathan Potter's color requester. Send $5.00 to obtain a disk",
- "containing source code and updated program.",
- "",
- " Comments, questions, bug reports, source requests:",
- "",
- " Jerry D. Hedden",
- " 28 Windemere Dr.",
- " Sicklerville, NJ 08081",
- " Phone: (609)629-3975",
- " Email: Hedden@ESDSDF.DNet.GE.com",
- NULL
- };
-
-
- info()
- {
- register long line;
- register struct Window *info_window;
- register struct IntuiMessage *msg;
- register ULONG class;
- register short all_done;
-
- MyWindow.IDCMPFlags = CLOSEWINDOW;
- MyWindow.Flags = SIMPLE_REFRESH|NOCAREREFRESH|ACTIVATE|WINDOWCLOSE;
- MyWindow.Title = (UBYTE *)InfoTitle;
-
- if (!(info_window = OpenWindow(&MyWindow))) return;
-
- for (line = 0; Text.IText = (UBYTE *)InfoText[line]; line++)
- PrintIText(info_window->RPort,&Text,TEXT_MARGIN,TEXT_START+(line<<3));
-
- for (all_done=0; !all_done; ) {
- _WaitPort(info_window->UserPort);
- while (msg = _GetMsg(info_window->UserPort)) {
- class = msg->Class;
- _ReplyMsg(msg);
- if (class == CLOSEWINDOW) all_done = 1;
- }
- }
- CloseWindow(info_window);
- }
-
-
- /*** common requester stuff ***/
-
- #define RESET 41
- #define CANCEL 42
- #define OKAY 43
-
- short border_xy[] = {0,0, 115,0, 115,10, 0,10, 0,0};
- struct Border MyBorder = {-1,-1,4,0,JAM1,5,border_xy,NULL};
-
- struct IntuiText
- OkayText = {2,0,JAM1, 41,1,NULL,(UBYTE *)"OKAY", NULL},
- ResetText = {3,0,JAM1, 37,1,NULL,(UBYTE *)"RESET", NULL},
- CancelText = {1,0,JAM1, 33,1,NULL,(UBYTE *)"CANCEL",NULL};
-
- struct Image PropImage1, PropImage2, PropImage3;
-
- struct Window *ReqWindow;
-
-
- /*** Color Requester ***/
-
-
- #define RED 31
- #define GREEN 32
- #define BLUE 33
-
- struct IntuiText
- RedText = {1,0,JAM1,-14,2,NULL,(UBYTE *)"R",NULL},
- GreenText = {2,0,JAM1,-14,2,NULL,(UBYTE *)"G",NULL},
- BlueText = {4,0,JAM1,-14,2,NULL,(UBYTE *)"B",NULL},
- ValuesText = {0,1,JAM2, 0,0,NULL,(UBYTE *)"RGB",NULL};
-
- struct PropInfo
- RedProp = {AUTOKNOB|FREEHORIZ,0,0,0x1000},
- GreenProp = {AUTOKNOB|FREEHORIZ,0,0,0x1000},
- BlueProp = {AUTOKNOB|FREEHORIZ,0,0,0x1000};
-
- struct Image CurColorImage = {0,0,235,8,1,NULL,0,1,NULL};
-
- struct Gadget
- RedCGadg = {NULL,24,54,100,11,
- GADGHNONE|GADGIMAGE,RELVERIFY|GADGIMMEDIATE,PROPGADGET,
- (APTR)&PropImage1,NULL,&RedText,NULL,(APTR)&RedProp,RED,NULL},
- GreenCGadg = {&RedCGadg,24,66,100,11,
- GADGHNONE|GADGIMAGE,RELVERIFY|GADGIMMEDIATE,PROPGADGET,
- (APTR)&PropImage2,NULL,&GreenText,NULL,(APTR)&GreenProp,GREEN,NULL},
- BlueCGadg = {&GreenCGadg,24,78,100,11,
- GADGHNONE|GADGIMAGE,RELVERIFY|GADGIMMEDIATE,PROPGADGET,
- (APTR)&PropImage3,NULL,&BlueText,NULL,(APTR)&BlueProp,BLUE,NULL},
- OkayCGadg = {&BlueCGadg,130,79,114,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
- (APTR)&MyBorder,NULL,&OkayText,NULL,NULL,OKAY,NULL},
- ResetCGadg = {&OkayCGadg,130,67,114,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
- (APTR)&MyBorder,NULL,&ResetText,NULL,NULL,RESET,NULL},
- CancelCGadg = {&ResetCGadg,130,55,114,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
- (APTR)&MyBorder,NULL,&CancelText,NULL,NULL,CANCEL,NULL};
-
- struct NewWindow ColorNewWindow={
- 40,23,255,93,1,4,GADGETUP|GADGETDOWN|MOUSEBUTTONS|RAWKEY,
- ACTIVATE|SIMPLE_REFRESH|NOCAREREFRESH|RMBTRAP,
- &CancelCGadg,NULL,(UBYTE *)" 4D Navigator Color Requester",
- NULL,NULL,0,0,0,0,CUSTOMSCREEN};
-
- long CurColor;
-
-
- ColorRequester(ColorSet)
- short ColorSet;
- {
- register long i;
- register ULONG Class;
- register USHORT Code, GadgetID;
- register struct IntuiMessage *msg;
-
- ColorNewWindow.Screen = screen;
- if (!(ReqWindow = OpenWindow(&ColorNewWindow))) return;
-
- for (i=0; i < (1<<PLANES); i++)
- ColorTables[2][i] = ColorTables[ColorSet][i];
-
- DrawPalette(PLANES);
- CurColorImage.PlaneOnOff = CurColor = 1;
- ValuesText.FrontPen = CurColor^((1<<PLANES)-1);
- ValuesText.BackPen = 1;
- DrawImage(ReqWindow->RPort,&CurColorImage,10L,45L);
- SetRGBProps();
-
- FOREVER {
- _WaitPort(ReqWindow->UserPort);
- while (msg = _GetMsg(ReqWindow->UserPort)) {
- Class = msg->Class; Code = msg->Code;
- if (Class == GADGETUP || Class == GADGETDOWN)
- GadgetID = ((struct Gadget *)msg->IAddress)->GadgetID;
- _ReplyMsg(msg);
- switch (Class) {
- case MOUSEBUTTONS: {
- long x,y;
- long NewColor, ReadPixel();
- if (Code != SELECTDOWN) break;
- x=ReqWindow->MouseX; y=ReqWindow->MouseY;
- if (x<12 || x>243 || y<15 || y>40) break;
- if (CurColor == (NewColor = ReadPixel(ReqWindow->RPort,x,y))) break;
- CurColorImage.PlaneOnOff = CurColor = NewColor;
- DrawImage(ReqWindow->RPort,&CurColorImage,10L,45L);
- SetRGBProps();
- break;
- }
- case GADGETDOWN:
- if (GadgetID >= RED && GadgetID <= BLUE) {
- do {
- ReadRGBProps();
- } while (!(msg = _GetMsg(ReqWindow->UserPort)));
- _ReplyMsg(msg);
- ReadRGBProps();
- }
- break;
- case RAWKEY:
- if (Code != ESCAPE) break;
- GadgetID = RESET;
- case GADGETUP:
- switch (GadgetID) {
- case RESET:
- for (i=0; i < (1<<PLANES); i++)
- ColorTables[2][i] = ColorTables[ColorSet][i];
- LoadRGB4(vp, &ColorTables[2][0], 1L<<PLANES);
- SetRGBProps();
- break;
- case OKAY:
- for (i=0; i < (1<<PLANES); i++)
- ColorTables[ColorSet][i] = ColorTables[2][i];
- case CANCEL:
- LoadRGB4(vp, &ColorTables[ColorSet][0], 1L<<PLANES);
- while (msg = _GetMsg(ReqWindow->UserPort)) _ReplyMsg(msg);
- CloseWindow(ReqWindow);
- return;
- }
- }
- }
- }
- }
-
-
- SetRGBProps()
- {
- register UWORD cval = ColorTables[2][CurColor];
- NewModifyProp(&RedCGadg, ReqWindow,0L,(long)(FREEHORIZ|AUTOKNOB),
- (long)(((cval>>8)&0xf)*0x1111),0L,0x1000L,0L,1L);
- NewModifyProp(&GreenCGadg,ReqWindow,0L,(long)(FREEHORIZ|AUTOKNOB),
- (long)(((cval>>4)&0xf)*0x1111),0L,0x1000L,0L,1L);
- NewModifyProp(&BlueCGadg, ReqWindow,0L,(long)(FREEHORIZ|AUTOKNOB),
- (long)((cval&0xf)*0x1111),0L,0x1000L,0L,1L);
- ShowRGBValues();
- }
-
-
- ReadRGBProps()
- {
- register long re,gr,bl;
-
- re = RedProp. HorizPot >> 12;
- gr = GreenProp.HorizPot >> 12;
- bl = BlueProp. HorizPot >> 12;
- ColorTables[2][CurColor] = (re<<8)|(gr<<4)|bl;
- SetRGB4(vp,CurColor,re,gr,bl);
- ShowRGBValues();
- }
-
-
- char *hex = "0123456789ABCDEF";
-
- ShowRGBValues()
- {
- register UWORD cval = ColorTables[2][CurColor];
- ValuesText.IText[0] = hex[(cval>>8)&0xf];
- ValuesText.IText[1] = hex[(cval>>4)&0xf];
- ValuesText.IText[2] = hex[ cval &0xf];
- ValuesText.FrontPen = CurColor^((1<<PLANES)-1);
- ValuesText.BackPen = CurColor;
- PrintIText(ReqWindow->RPort,&ValuesText,115L,45L);
- }
-
-
- DrawPalette(depth)
- int depth;
- {
- long w,h,ox,x,y,i;
-
- #if PLANES>3
- if (depth==4)
- { w=29; h=12; ox=13; }
- else if (depth==5)
- { w=14; h=12; ox=17; }
- else
- #endif
- { w=235/(1<<depth); h=25; ox=12; }
- i=0; x=ox; y=15;
- for (i=0; i<(1<<depth); i++) {
- SetAPen(ReqWindow->RPort,i);
- RectFill(ReqWindow->RPort,x,y,x+w,y+h);
- #if PLANES>3
- if (depth>3 && i==(1<<(depth-1))-1) {
- x=ox; y+=h;
- } else
- #endif
- x+=w;
- }
- }
-
-
- /*** View Requester ***/
-
- #define FRONT 31
- #define BACK 32
- #define SCALE 33
-
- #define TEXTX 5L
- #define TEXTY -10L
- #define GADGX 8L
- #define FGADY 25L
- #define BGADY 50L
- #define SGADY 75L
- #define FBODY 126L
- #define BBODY 126L
- #define SBODY 661L
-
- struct IntuiText
- FrontText = {6,0,JAM2,TEXTX,TEXTY,NULL,(UBYTE *)"Front Cutoff: ",NULL},
- BackText = {6,0,JAM2,TEXTX,TEXTY,NULL,(UBYTE *)"Rear Cutoff : ",NULL},
- ScaleText = {6,0,JAM2,TEXTX,TEXTY,NULL,(UBYTE *)"Scaling Factor: ",NULL};
-
- struct PropInfo
- FrontProp = {AUTOKNOB|FREEHORIZ,0,0,FBODY},
- BackProp = {AUTOKNOB|FREEHORIZ,0,0,BBODY},
- ScaleProp = {AUTOKNOB|FREEHORIZ,0,0,SBODY};
-
- struct Gadget
- FrontVGadg = {NULL, GADGX,FGADY, 640,11,
- GADGHNONE|GADGIMAGE, RELVERIFY|GADGIMMEDIATE, PROPGADGET,
- (APTR)&PropImage1, NULL, &FrontText, NULL, (APTR)&FrontProp, FRONT, NULL},
- BackVGadg = {&FrontVGadg, GADGX,BGADY, 640,11,
- GADGHNONE|GADGIMAGE, RELVERIFY|GADGIMMEDIATE, PROPGADGET,
- (APTR)&PropImage2, NULL, &BackText, NULL, (APTR)&BackProp, BACK, NULL},
- ScaleVGadg = {&BackVGadg, GADGX,SGADY, 265,11,
- GADGHNONE|GADGIMAGE, RELVERIFY|GADGIMMEDIATE, PROPGADGET,
- (APTR)&PropImage3, NULL, &ScaleText, NULL, (APTR)&ScaleProp, SCALE, NULL},
- OkayVGadg = {&ScaleVGadg, 285,SGADY+1, 114,9,
- GADGHCOMP, RELVERIFY, BOOLGADGET,
- (APTR)&MyBorder, NULL, &OkayText, NULL, NULL, OKAY, NULL},
- ResetVGadg = {&OkayVGadg, 409,SGADY+1, 114,9,
- GADGHCOMP, RELVERIFY, BOOLGADGET,
- (APTR)&MyBorder, NULL, &ResetText, NULL, NULL, RESET, NULL},
- CancelVGadg = {&ResetVGadg, 533,SGADY+1, 114,9,
- GADGHCOMP, RELVERIFY, BOOLGADGET,
- (APTR)&MyBorder, NULL, &CancelText, NULL, NULL, CANCEL, NULL};
-
- struct NewWindow ViewNewWindow={
- 0,50, 656,93, 1,4, GADGETUP|GADGETDOWN|MOUSEBUTTONS,
- ACTIVATE|SIMPLE_REFRESH|NOCAREREFRESH|RMBTRAP,
- &CancelVGadg,NULL,(UBYTE *)" 4D Navigator View Modifiers",
- NULL,NULL,0,0,0,0,CUSTOMSCREEN};
-
- short NewFront, NewBack, NewScale;
-
-
- ViewRequester()
- {
- register ULONG Class;
- register USHORT GadgetID;
- register struct IntuiMessage *msg;
-
- ViewNewWindow.Screen = screen;
- if (!(ReqWindow = OpenWindow(&ViewNewWindow))) return;
-
- SetViewProps();
-
- FOREVER {
- _WaitPort(ReqWindow->UserPort);
- while (msg = _GetMsg(ReqWindow->UserPort)) {
- Class = msg->Class;
- if (Class == GADGETUP || Class == GADGETDOWN)
- GadgetID = ((struct Gadget *)msg->IAddress)->GadgetID;
- _ReplyMsg(msg);
- switch (Class) {
- case GADGETDOWN:
- if (GadgetID >= FRONT && GadgetID <= SCALE) {
- do {
- ReadViewProps();
- } while (!(msg = _GetMsg(ReqWindow->UserPort)));
- _ReplyMsg(msg);
- ReadViewProps();
- }
- break;
- case GADGETUP:
- switch (GadgetID) {
- case RESET:
- SetViewProps();
- break;
- case OKAY:
- if (NewFront == NewBack)
- if (NewFront > 0)
- NewFront -= 100;
- else
- NewBack += 100;
- if (NewFront < NewBack) {
- FrontLimit = NewFront;
- BackLimit = NewBack;
- } else {
- FrontLimit = NewBack;
- BackLimit = NewFront;
- }
- ScaleFactor = NewScale;
- case CANCEL:
- while (msg=_GetMsg(ReqWindow->UserPort)) _ReplyMsg(msg);
- CloseWindow(ReqWindow);
- return;
- }
- }
- }
- }
- }
-
-
- SetViewProps()
- {
- NewFront = FrontLimit;
- NewBack = BackLimit;
- NewScale = ScaleFactor;
- NewModifyProp(&FrontVGadg,ReqWindow,0L,(long)(FREEHORIZ|AUTOKNOB),
- (ULONG)(((NewFront/100)+258)*127),0L,FBODY,0L,1L);
- NewModifyProp(&BackVGadg, ReqWindow,0L,(long)(FREEHORIZ|AUTOKNOB),
- (ULONG)(((NewBack /100)+258)*127),0L,BBODY,0L,1L);
- NewModifyProp(&ScaleVGadg,ReqWindow,0L,(long)(FREEHORIZ|AUTOKNOB),
- (ULONG)((NewScale-1)*661),0L,SBODY,0L,1L);
- ShowViewValues();
- }
-
-
- ReadViewProps()
- {
- NewFront = (((USHORT)FrontProp.HorizPot/127)-258)*100;
- NewBack = (((USHORT)BackProp .HorizPot/127)-258)*100;
- NewScale = ( (USHORT)ScaleProp.HorizPot/656)+1;
- ShowViewValues();
- }
-
-
- ShowViewValues()
- {
- SPrintF(&FrontText.IText[14],"%6d",NewFront);
- SPrintF(&BackText. IText[14],"%6d",NewBack);
- SPrintF(&ScaleText.IText[17],"%3d",NewScale);
- PrintIText(ReqWindow->RPort,&FrontText,GADGX,FGADY);
- PrintIText(ReqWindow->RPort,&BackText, GADGX,BGADY);
- PrintIText(ReqWindow->RPort,&ScaleText,GADGX,SGADY);
- }
-
-
- #asm
-
- ; A small sprintf() function using the Exec library RawDoFmt() function
-
- public _SysBase,_LVORawDoFmt
-
- public _SPrintF
- _SPrintF
- movem.l a2/a3,-(sp)
- move.l 16(sp),a0
- lea.l 20(sp),a1
- lea.l put_ch(pc),a2
- move.l 12(sp),a3
- move.l _SysBase,a6
- jsr _LVORawDoFmt(a6)
- movem.l (sp)+,a2/a3
- rts
-
- put_ch move.b d0,(a3)+
- rts
-
-
- ; Stubs for accessing the math libraries
-
- public _MathBase
- public _MathTransBase
-
- _LVOSPCeil equ -96
- _LVOSPFloor equ -90
- _LVOSPDiv equ -84
- _LVOSPMul equ -78
- _LVOSPSub equ -72
- _LVOSPAdd equ -66
- _LVOSPNeg equ -60
- _LVOSPAbs equ -54
- _LVOSPTst equ -48
- _LVOSPCmp equ -42
- _LVOSPFlt equ -36
- _LVOSPFix equ -30
-
- _LVOSPLog10 equ -126
- _LVOSPAcos equ -120
- _LVOSPAsin equ -114
- _LVOSPFieee equ -108
- _LVOSPTieee equ -102
- _LVOSPSqrt equ -96
- _LVOSPPow equ -90
- _LVOSPLog equ -84
- _LVOSPExp equ -78
- _LVOSPTanh equ -72
- _LVOSPCosh equ -66
- _LVOSPSinh equ -60
- _LVOSPSincos equ -54
- _LVOSPTan equ -48
- _LVOSPCos equ -42
- _LVOSPSin equ -36
- _LVOSPAtan equ -30
-
-
- public _SPFix
- _SPFix
- move.l 4(sp),d0
- move.l _MathBase,a6
- jmp _LVOSPFix(a6)
-
- public _SPFlt
- _SPFlt
- move.l 4(sp),d0
- move.l _MathBase,a6
- jmp _LVOSPFlt(a6)
-
- public _SPCmp
- _SPCmp
- move.l 4(sp),d1
- move.l 12(sp),d0
- move.l _MathBase,a6
- jmp _LVOSPCmp(a6)
-
- public _SPNeg
- _SPNeg
- move.l 4(sp),d0
- move.l _MathBase,a6
- jmp _LVOSPNeg(a6)
-
- public _SPAdd
- _SPAdd
- move.l 4(sp),d1
- move.l 12(sp),d0
- move.l _MathBase,a6
- jmp _LVOSPAdd(a6)
-
- public _SPSub
- _SPSub
- move.l 4(sp),d1
- move.l 12(sp),d0
- move.l _MathBase,a6
- jmp _LVOSPSub(a6)
-
- public _SPMul
- _SPMul
- move.l 4(sp),d1
- move.l 12(sp),d0
- move.l _MathBase,a6
- jmp _LVOSPMul(a6)
-
- public _SPDiv
- _SPDiv
- move.l 4(sp),d1
- move.l 12(sp),d0
- move.l _MathBase,a6
- jmp _LVOSPDiv(a6)
-
- public _SPTst
- _SPTst
- move.l 4(sp),d1
- move.l _MathBase,a6
- jmp _LVOSPTst(a6)
-
- ; public _SPAbs
- ;_SPAbs
- ; move.l 4(sp),d0
- ; move.l _MathBase,a6
- ; jmp _LVOSPAbs(a6)
- ;
- ; public _SPCeil
- ;_SPCeil
- ; move.l 4(sp),d0
- ; move.l _MathBase,a6
- ; jmp _LVOSPCeil(a6)
- ;
- ; public _SPFloor
- ;_SPFloor
- ; move.l 4(sp),d0
- ; move.l _MathBase,a6
- ; jmp _LVOSPFloor(a6)
-
-
- public _SPSqrt
- _SPSqrt
- move.l 4(sp),d0
- move.l _MathTransBase,a6
- jmp _LVOSPSqrt(a6)
-
- public _SPSincos
- _SPSincos
- move.l 4(sp),d1
- move.l 8(sp),d0
- move.l _MathTransBase,a6
- jmp _LVOSPSincos(a6)
-
- ; public _SPSin
- ;_SPSin
- ; move.l 4(sp),d0
- ; move.l _MathTransBase,a6
- ; jmp _LVOSPSin(a6)
- ;
- ; public _SPCos
- ;_SPCos
- ; move.l 4(sp),d0
- ; move.l _MathTransBase,a6
- ; jmp _LVOSPCos(a6)
- ;
- ; public _SPTan
- ;_SPTan
- ; move.l 4(sp),d0
- ; move.l _MathTransBase,a6
- ; jmp _LVOSPTan(a6)
- ;
- ; public _SPAsin
- ;_SPAsin
- ; move.l 4(sp),d0
- ; move.l _MathTransBase,a6
- ; jmp _LVOSPAsin(a6)
-
- public _SPAcos
- _SPAcos
- move.l 4(sp),d0
- move.l _MathTransBase,a6
- jmp _LVOSPAcos(a6)
-
- ; public _SPAtan
- ;_SPAtan
- ; move.l 4(sp),d0
- ; move.l _MathTransBase,a6
- ; jmp _LVOSPAtan(a6)
- ;
- ; public _SPSinh
- ;_SPSinh
- ; move.l 4(sp),d0
- ; move.l _MathTransBase,a6
- ; jmp _LVOSPSinh(a6)
- ;
- ; public _SPCosh
- ;_SPCosh
- ; move.l 4(sp),d0
- ; move.l _MathTransBase,a6
- ; jmp _LVOSPCosh(a6)
- ;
- ; public _SPTanh
- ;_SPTanh
- ; move.l 4(sp),d0
- ; move.l _MathTransBase,a6
- ; jmp _LVOSPTanh(a6)
- ;
- ; public _SPExp
- ;_SPExp
- ; move.l 4(sp),d0
- ; move.l _MathTransBase,a6
- ; jmp _LVOSPExp(a6)
- ;
- ; public _SPLog
- ;_SPLog
- ; move.l 4(sp),d0
- ; move.l _MathTransBase,a6
- ; jmp _LVOSPLog(a6)
- ;
- ; public _SPPow
- ;_SPPow
- ; move.l 4(sp),d1
- ; move.l 12(sp),d0
- ; move.l _MathTransBase,a6
- ; jmp _LVOSPPow(a6)
- ;
- ; public _SPLog10
- ;_SPLog10
- ; move.l 4(sp),d0
- ; move.l _MathTransBase,a6
- ; jmp _LVOSPLog10(a6)
- ;
- ; public _SPTieee
- ;_SPTieee
- ; move.l 4(sp),d0
- ; move.l _MathTransBase,a6
- ; jmp _LVOSPTieee(a6)
- ;
- ; public _SPFieee
- ;_SPFieee
- ; move.l 4(sp),d0
- ; move.l _MathTransBase,a6
- ; jmp _LVOSPFieee(a6)
-
- #endasm
-
-
- #if TIMING
-
- PrintTime(what,start,finish)
- char *what;
- long *start,*finish;
- {
- long dd;
- register long hh, mm, ss, xx; /*** d4, d5, d6, d7 ***/
-
- if (start[2] > finish[2]) { finish[1]--; finish[2] += 3000; }
- if (start[1] > finish[1]) { finish[0]--; finish[1] += 1440; }
- dd=finish[0]-start[0]; mm=finish[1]-start[1]; xx=finish[2]-start[2];
- #asm
- move.l d5,d4 ; hh = mm/60
- divu #60,d4
- ext.l d4
- move.w d4,d0 ; mm -= hh*60
- mulu #60,d0
- sub.l d0,d5
- move.l d7,d6 ; ss = xx/50
- divu #50,d6
- ext.l d6
- move.w d6,d0 ; xx -= ss*50
- mulu #50,d0
- sub.l d0,d7
- asl.l #1,d7 ; xx *= 2
- #endasm
- PrintF("%s: %ld-%02ld:%02ld:%02ld.%02ld\n",what,dd,hh,mm,ss,xx);
- }
-
- #endif
-
-
- #if DEBUG
-
- dump_screen_plot()
- {
- register short plong,lat,elong;
- register long index;
- register short *toplot, *toget;
- long num;
- short firstx, firsty;
- short plot_buf[(SEGMENTS+1)*2];
- long file,_Open();
-
- if (!(file = _Open("ram:lines.dat",1006L))) return;
-
- toplot = plot_buf;
-
- toget = e2d;
- firstx = DONT_PLOT;
- if ((toplot[num=0] = toget[0]) != DONT_PLOT) {
- firstx = toplot[0]; firsty = toplot[1] = toget[1]; num=2;
- }
- for (elong=2; elong<SEGMENTS*2; elong+=2)
- if ((toplot[num] = toget[elong]) != DONT_PLOT) {
- toplot[++num] = toget[elong+1]; num++;
- } else {
- if (num >= 4) {
- plot_dump(file,"EQUATOR",0,0,elong/2,num,toplot);
- }
- num = 0;
- }
- if (num >= 2 && firstx != DONT_PLOT) {
- toplot[num++] = firstx; toplot[num++] = firsty;
- }
- if (num >= 4) {
- plot_dump(file,"EQUATOR",0,0,elong/2,num,toplot);
- }
-
- toget = p2d;
- firstx = DONT_PLOT;
- if ((toplot[num=0] = toget[0]) != DONT_PLOT) {
- firstx = toplot[0]; firsty = toplot[1] = toget[1]; num=2;
- }
- for (plong=2; plong<SEGMENTS*2; plong+=2)
- if ((toplot[num] = toget[plong]) != DONT_PLOT) {
- toplot[++num] = toget[plong+1]; num++;
- } else {
- if (num >= 4) {
- plot_dump(file,"POLAR RING",plong/2,0,0,num,toplot);
- }
- num = 0;
- }
- if (num >= 2 && firstx != DONT_PLOT) {
- toplot[num++] = firstx; toplot[num++] = firsty;
- }
- if (num >= 4) {
- plot_dump(file,"POLAR RING",plong/2,0,0,num,toplot);
- }
-
- toget = x2d;
- for (lat=0; lat<LATRNG; lat++)
- for (elong=0; elong<SEGMENTS; elong++) {
- firstx = DONT_PLOT;
- if ((toplot[num=0] = toget[index=INDX(0,lat,elong)*2]) != DONT_PLOT) {
- firstx = toplot[0]; firsty = toplot[1] = toget[index+1]; num=2;
- }
- for (plong=1; plong<SEGMENTS; plong++)
- if ((toplot[num]=toget[index=INDX(plong,lat,elong)*2])!=DONT_PLOT) {
- toplot[++num] = toget[index+1]; num++;
- } else {
- if (num >= 4) {
- plot_dump(file,"CIRCUMPOLAR",plong,lat+1,elong,num,toplot);
- }
- num = 0;
- }
- if (num >= 2 && firstx != DONT_PLOT) {
- toplot[num++] = firstx; toplot[num++] = firsty;
- }
- if (num >= 4) {
- plot_dump(file,"CIRCUMPOLAR",plong,lat+1,elong,num,toplot);
- }
- }
-
- for (lat=0; lat<LATRNG; lat++)
- for (plong=0; plong<SEGMENTS; plong++) {
- firstx = DONT_PLOT;
- if ((toplot[num=0] = toget[index=INDX(plong,lat,0)*2]) != DONT_PLOT) {
- firstx = toplot[0]; firsty = toplot[1] = toget[index+1]; num=2;
- }
- for (elong=1; elong<SEGMENTS; elong++)
- if ((toplot[num]=toget[index=INDX(plong,lat,elong)*2])!=DONT_PLOT) {
- toplot[++num] = toget[index+1]; num++;
- } else {
- if (num >= 4) {
- plot_dump(file,"CIRCUMEQUATORIAL",plong,lat+1,elong,num,toplot);
- }
- num = 0;
- }
- if (num >= 2 && firstx != DONT_PLOT) {
- toplot[num++] = firstx; toplot[num++] = firsty;
- }
- if (num >= 4) {
- plot_dump(file,"CIRCUMEQUATORIAL",plong,lat+1,elong,num,toplot);
- }
- }
-
- for (elong=0; elong<SEGMENTS; elong++)
- for (plong=0; plong<SEGMENTS; plong++) {
- num = 0;
- if (!(elong&1))
- if ((toplot[0] = e2d[plong*2]) != DONT_PLOT) {
- toplot[1] = e2d[plong*2+1]; num=2;
- }
- for (lat=0; lat<LATRNG; lat++)
- if ((toplot[num]=toget[index=INDX(plong,lat,elong)*2])!=DONT_PLOT) {
- toplot[++num] = toget[index+1]; num++;
- } else {
- if (num >= 4) {
- plot_dump(file,"LONGITUDE LINES",plong,lat+1,elong,num,toplot);
- }
- num = 0;
- }
- if (!(plong&1))
- if ((toplot[num] = p2d[elong*2]) != DONT_PLOT) {
- toplot[++num] = p2d[elong*2+1]; num++;
- }
- if (num >= 4) {
- plot_dump(file,"LONGITUDE LINES",plong,lat+1,elong,num,toplot);
- }
- }
-
- _Close(file);
- }
-
-
- plot_dump(file,label,plong,lat,elong,num,toplot)
- long file;
- char *label;
- short plong,lat,elong;
- long num;
- short *toplot;
- {
- long i;
-
- FPrintF(file,"%s\nplong = %d lat = %d elong = %d num = %ld\n",
- label,plong*INTERVAL,lat*INTERVAL,elong*INTERVAL,num);
- for (i=0; i < num; i+=2)
- FPrintF(file,"%5d\t%5d\n",toplot[i],toplot[i+1]);
- FPrintF(file,"\n");
- }
-
-
- dump_coordinates(all)
- int all;
- {
- short plong,lat,elong;
- long file, _Open();
-
- if (!(file = _Open("ram:coord.dat",1006L))) return;
-
- for (plong=0; plong<SEGMENTS; plong++)
- for (lat=0; lat<LATRNG; lat++)
- for (elong=0; elong<SEGMENTS; elong++)
- if (all || x2d[INDX(plong,lat,elong)*2+X] != DONT_PLOT)
- FPrintF(file,
- "x[%3d][%2d][%3d] = (%6d,%6d,%6d,%6d) (%6d,%6d,%6d) (%6d,%6d)\n",
- plong*INTERVAL, (lat+1)*INTERVAL, elong*INTERVAL,
- x4d[INDX(plong,lat,elong)*4+X], x4d[INDX(plong,lat,elong)*4+Y],
- x4d[INDX(plong,lat,elong)*4+Z], x4d[INDX(plong,lat,elong)*4+W],
- x3d[INDX(plong,lat,elong)*3+X], x3d[INDX(plong,lat,elong)*3+Y],
- x3d[INDX(plong,lat,elong)*3+Z],
- x2d[INDX(plong,lat,elong)*2+X], x2d[INDX(plong,lat,elong)*2+Y]);
-
- for (plong=0; plong<SEGMENTS; plong++)
- if (all || p2d[plong*2+X] != DONT_PLOT)
- FPrintF(file, "p[%3d] = (%6d,%6d,%6d,%6d) (%6d,%6d,%6d) (%6d,%6d)\n",
- plong*INTERVAL,
- p4d[plong*4+X], p4d[plong*4+Y], p4d[plong*4+Z], p4d[plong*4+W],
- p3d[plong*3+X], p3d[plong*3+Y], p3d[plong*3+Z],
- p2d[plong*2+X], p2d[plong*2+Y]);
-
- for (elong=0; elong<SEGMENTS; elong++)
- if (all || e2d[elong*2+X] != DONT_PLOT)
- FPrintF(file, "e[%3d] = (%6d,%6d,%6d,%6d) (%6d,%6d,%6d) (%6d,%6d)\n",
- elong*INTERVAL,
- e4d[elong*4+X], e4d[elong*4+Y], e4d[elong*4+Z], e4d[elong*4+W],
- e3d[elong*3+X], e3d[elong*3+Y], e3d[elong*3+Z],
- e2d[elong*2+X], e2d[elong*2+Y]);
-
- _Close(file);
- }
-
- #endif
-
-
- #if TIMING | DEBUG
-
- #asm
- ; FUNCTION IMPLEMENTATION
- ; void PrintF(fmt_str,args...) FPrintF(Output(),fmt_str,args...)
- ; void FPrintF(fh,fmt_str,args...)
- ;
- ; These functions have no return value, unlike the standard 'C' versions
- ; that return the number of items matched in the format string.
- ;
- ; Note that PrintF and FPrintF use stack space for buffering the resulting
- ; string. The length of the resulting string is set up below to be limited
- ; to < 256 characters. If longer strings are needed, increase the buffer
- ; size (ResBuf), but beware of stack overflow when doing so.
-
- ;Globals
- public _SysBase,_DOSBase
- public _LVORawDoFmt,_LVOWrite,_LVOOutput
-
- ResBuf equ 256
-
- public _PrintF
- _PrintF
- move.l _DOSBase,a6 ; get file handle of current output
- jsr _LVOOutput(a6) ; using Output()
- move.l (sp),-(sp) ; duplicate return address
- move.l d0,4(sp) ; put file handle "under" it
- ; fall into FPrintF
-
- public _FPrintF
- _FPrintF
- movem.l a2/a3,-(sp) ; don't need to save registers d0-3,a0-1,a6
-
- move.l 16(sp),a0 ; format string
- lea.l 20(sp),a1 ; data stream
- lea.l put_char(pc),a2 ; output procedure called by RawDoFmt
-
- lea.l -ResBuf(sp),sp ; allocate some stack space where
- move.l sp,a3 ; put_ch will put characters from RawDoFmt
-
- move.l _SysBase,a6 ; do the magic
- jsr _LVORawDoFmt(a6) ; using RawDoFmt()
-
- move.l ResBuf+12(sp),d1 ; output file handle
- move.l sp,d2 ; the result string is on the stack
- moveq #0,d3
- move.w str_len,d3 ; string length
- beq.s 1$ ; ignore a zero length string
-
- move.l _DOSBase,a6 ; output the results
- jsr _LVOWrite(a6) ; using Write()
-
- 1$ move.w #-1,str_len ; reset for next time
- lea.l ResBuf(sp),sp ; release stack space
- movem.l (sp)+,a2/a3 ; restore registers
- rts ; all done
-
-
- ; length of the output string minus the terminating null
- dseg
- public str_len
- str_len dc.w -1
- cseg
-
- far data
- put_char
- addq.w #1,str_len ; add 1 to string length
- near data
- move.b d0,(a3)+ ; this "procedure" stuffs the characters from
- rts ; RawDoFmt into the destination buffer
-
- #endasm
-
- #endif
-